package com.nkym.wypan.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nkym.wypan.constants.CommonConstants;
import com.nkym.wypan.constants.DeleteStatusConstant;
import com.nkym.wypan.enums.ResponseStatus;
import com.nkym.wypan.enums.chat.RoomMemberRoleEnum;
import com.nkym.wypan.exception.BusinessException;
import com.nkym.wypan.model.context.chat.CreateRoomContext;
import com.nkym.wypan.model.entity.chat.Room;
import com.nkym.wypan.model.entity.chat.RoomMember;
import com.nkym.wypan.model.req.chat.JoinRoomReq;
import com.nkym.wypan.model.req.chat.PageQueryRoomReq;
import com.nkym.wypan.model.resp.socket.PageQueryRoomVO;
import com.nkym.wypan.model.resp.socket.RoomVO;
import com.nkym.wypan.service.RoomMemberService;
import com.nkym.wypan.service.RoomService;
import com.nkym.wypan.mapper.RoomMapper;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.nkym.wypan.constants.CommonConstants.*;
import static com.nkym.wypan.constants.DeleteStatusConstant.*;
import static com.nkym.wypan.enums.ResponseStatus.*;
import static com.nkym.wypan.enums.chat.RoomMemberRoleEnum.*;

/**
 * @author 19637
 * @description 针对表【wy_pan_room】的数据库操作Service实现
 * @createDate 2023-11-10 14:27:25
 */
@Service
public class RoomServiceImpl extends ServiceImpl<RoomMapper, Room>
        implements RoomService {
    @Resource
    RoomMapper roomMapper;
    @Resource
    RoomMemberService roomMemberService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createRoom(CreateRoomContext context) {
        String name = context.getName();
        Long userId = context.getUserId();
        Room room = new Room();
        room.setName(name);
        room.setRoomOwnerId(userId);
        room.setAvatar("");
        room.setDeleteStatus(NO);
        //创建群聊
        if (!save(room)) {
            throw new BusinessException(CREATE_ROOM_FAIL);
        }
        //插入 群成员自己
        RoomMember roomMember = buildRoomMember(room.getRoomId(), userId, OWNER);
        if (!roomMemberService.save(roomMember)) {
            throw new BusinessException(CREATE_ROOM_FAIL);
        }
    }

    @Override
    public void joinRoom(Long userId, JoinRoomReq req) {
        Long roomId = req.getRoomId();
        boolean isExists = checkRoomIsExists(roomId);
        if (!isExists) {
            throw new BusinessException(ROOM_NOT_EXISTS);
        }
        boolean isRoomMember = roomMemberService.checkUserIsRoomMember(roomId, userId);
        if (isRoomMember) {
            throw new BusinessException(REPEAT_JOIN_ROOM);
        }
        RoomMember roomMember = buildRoomMember(roomId, userId, NORMAL);
        boolean save = roomMemberService.save(roomMember);
        if (!save) {

            throw new BusinessException(JOIN_ROOM_FAIL);
        }
    }

    @Override
    public boolean checkRoomIsExists(Long roomId) {
        Room room = getOne(new LambdaQueryWrapper<Room>()
                .eq(Room::getRoomId, roomId)
                .eq(Room::getDeleteStatus, NO));
        return room != null;
    }

    @Override
    public PageQueryRoomVO pageGetRoom(Long userId, PageQueryRoomReq req) {
        Page<Room> page = new Page<>(req.getPageNow(), req.getPageSize());
        page.setSearchCount(false);
        //包括自己的群和全员大群
        Page<Room> roomPage = page(page, new LambdaQueryWrapper<Room>()
                .and(r -> {
                    r.eq(Room::getRoomOwnerId, userId)
                            .or()
                            .eq(Room::getRoomId, Zero);
                })
                .and(roomLambdaQueryWrapper -> roomLambdaQueryWrapper.eq(Room::getDeleteStatus, NO)));
        PageQueryRoomVO vo = buildPageQueryRoomVO(roomPage);
        return vo;
    }


    /**
     * -----------------------private--------------------------
     */

    @NotNull
    private PageQueryRoomVO buildPageQueryRoomVO(Page<Room> roomPage) {
        List<RoomVO> records = roomPage.getRecords().stream().map(RoomVO::covert).collect(Collectors.toList());
        PageQueryRoomVO vo = new PageQueryRoomVO();
        vo.setRecord(records);
        int size = records.size();

        vo.setTotalPage(size/roomPage.getSize() + 1);
        return vo;
    }

    private RoomMember buildRoomMember(Long roomId, Long userId, RoomMemberRoleEnum e) {
        RoomMember member = new RoomMember();
        member.setRoomId(roomId);
        member.setUid(userId);
        member.setRole(e.getCode());
        return member;
    }
}




